#ifndef __CALLBACK_H__
#define __CALLBACK_H__

#include <windows.h>

struct widget_def;

typedef struct callback_def
{
    // handler to the widgets window
    HWND hwnd;
    // pointer to the widget
    struct widget_def *widget;
    // pointer to the next callback node in the list
    struct callback_def *next;
    // callback function
    // function to call to free the widgets memory
    void (*free)(struct widget_def*);
    // called if the window have been closed
    BOOL (*close)(struct widget_def*);
    // called when the screen need to be redraw
    void (*paint)(struct widget_def*,HDC);
    // mouse event
    void (*mouse_move)(struct widget_def*,int32_t,int32_t,uint32_t);
    void (*lbutton_down)(struct widget_def*,int32_t,int32_t,uint32_t);
    void (*lbutton_up)(struct widget_def*,int32_t,int32_t,uint32_t);
    void (*rbutton_down)(struct widget_def*,int32_t,int32_t,uint32_t);
    void (*rbutton_up)(struct widget_def*,int32_t,int32_t,uint32_t);
    void (*mouse_enter)(struct widget_def*,int32_t,int32_t,uint32_t);
    void (*mouse_leave)(struct widget_def*);
    // keyboard event
    void (*key_down)(struct widget_def*,uint32_t);
    void (*key_up)(struct widget_def*,uint32_t);
} callback_t;

/*! Allocate memory for the callback hash table
 *
 * \param size of hash table, more widget = larger table
 */
void callback_initialize(size_t);

/*! Bind a window handler to widget information
 *
 * \param hwnd: handler to the window to bind
 * \note A hwnd can only be bind ones.
 */
callback_t *callback_bind(HWND,struct widget_def*);

/*! Find callback node for a given window handler
 *
 * \param hwnd: handler to the window
 * \return pointer to the callback function, NULL if not found
 */ 
callback_t *callback_find(HWND);

/* Free memmory for all widget and remove them from the hash table.
 */
void callback_finalize();

/*! Default free callback function, free the widget from the memory
 *
 * \param self: pointer to its widget
 *
 * \note The programmer do not need to free memory for widget at then end of
 * the program, this is done automaticaly.
 */
void callback_free(struct widget_def*);

/*! Default close callback function, called when the widget closes.
 *
 * \param self: pointer to its widget
 * \return TRUE if the application should be destroyed
 */
BOOL callback_close(struct widget_def*);
/*! Default paint callback function, called when widget need redrawing.
 *
 * \param self: pointer to its widget
 */
void callback_paint(struct widget_def*,HDC);

/*! Default mouse move callback function, called when the mouse have moved
 *  above the widget
 *
 * \param self: pointer to its widget 
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag, indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void callback_mouse_move(struct widget_def*,int32_t,int32_t,uint32_t);

/*! Default mouse left button callback function, called when the user have
 *  pressed teh left mouse button.
 *
 * \param self: pointer to its widget
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void callback_lbutton_down(struct widget_def*,int32_t,int32_t,uint32_t);

/*! Default mouse left button callback function, called when the user have
 *  released the left mouse button.
 *
 * \param self: pointer to its widget
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void callback_lbutton_up(struct widget_def*,int32_t,int32_t,uint32_t);

/*! Default mouse right button callback function, called when the user have
 *  pressed the right mouse button.
 *
 * \param self: pointer to its self
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void callback_rbutton_down(struct widget_def*,int32_t,int32_t,uint32_t);

/*! Default mouse right button callback function, called when the user have
 *  released the right mouse button.
 * 
 * \param self: pointer to its widget
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */

void callback_rbutton_up(struct widget_def*,int32_t,int32_t,uint32_t);

/*! Default key button down callback function, called when the user have
 *  presed a key on the key board.
 *
 * \param self: pointer to its widget
 * \param vkey: virtual key pressed (ex. VK_A or VK_ESCAPE)
 */
void callback_key_down(struct widget_def*,uint32_t);

/*! Default key button up callback function, called when the user have
 *  released a key on the key board.
 *
 *  \param self: pointer to its widget
 *  \param vkey: virtual key released (ex. VK_A or VK_ESCAPE)
 */
void callback_key_up(struct widget_def*,uint32_t);

/*! Default mosue enter callback function, called when the mosue enter the
 *  window
 *
 * \param self: pointer to its widget
 * \param x: mouse x coordinate
 * \param y: mosue y coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void callback_mouse_enter(struct widget_def*,int32_t,int32_t,uint32_t);

/*! Default mouse leave callback function, called when the mouse leaves the
 *  window
 *
 * \param self: pointer to its widget
 */
void callback_mouse_leave(struct widget_def*);

#endif // __CALLBACK_H__

